<?php
/**
 * Working with roles, rules and resource
 * @author kenny
 * @since 2011
 */
class Users_Service_Acl extends Zend_Acl {
	
	/**
	 * @var Users_Service_Acl
	 */
	private static $_instance = null;
	
	/**
	 * @return Users_Service_Acl
	 */
	public function getInstance() {
		if(self::$_instance === null)
		{
			self::$_instance = new self();
		}
	}
	
	public function __construct() {
		$this->_loadResources();
		$this->_loadRoles();
		$this->_loadRules();
	}
	
	/**
	 * Loading resources
	 */
	private function _loadResources() {
		$model = new Users_Model_Resources();
		$resources = $model->fetchAll();
		foreach($resources as $resource) {
			$this->_loadResource();
		}
	}
	
	/**
	 * Loading resource
	 */
	private function _loadResource($resource) {
		$parent = $resource->findParentRow(new Users_Model_Resources(), 'Parent');
		if($parent) {
			$this->_loadResource($parent);
		}
		if(!$this->has(new Zend_Acl_Resource($resource->name))) {
			if($parent) {
				$this->addResource(new Zend_Acl_Resource($resource->name), $parent->name);
			} else {
				$this->addResource(new Zend_Acl_Resource($resource->name));
			}
		}
	}
	
	/**
	 * Loading roles
	 */
	private function _loadRoles() {
		$model = new Users_Model_Role();
		$roles = $model->fetchAll();
		foreach($roles as $role) {
			$this->_loadRole($role);
		}
	}
	
	/**
	 * Loading role
	 */
	private function _loadRole($role, $inheritanceChain = array()) {
		if(in_array($role->name, $inheritanceChain)) {
			$inheritanceChain[] = $role->name;
			throw new Zend_Exception('Role already exists in the inheritance chain: ' . implode('->', $inheritanceChain));
		}
		//родители
		$parents = $role->findManyToManyRowset(new Users_Model_Role(), new Users_Model_RoleParent(), 'Role', 'Parent');
		if($parents->count() > 0) {
			foreach ($parent as $parent) {
				$inheritanceChain[] = $role->name;
				$this->_loadRole($parent, $inheritanceChain);
			}
		}
		
		if(!$this->hasRole(new Zend_Acl_Role($role->name))) {
			if($parents->count() > 0) {
				$this->addRole(new Zend_Acl_Role($role->name), $this->_prepareArray($parents->toArray()));
			} else {
				$this->addRole(new Zend_Acl_Role($role->name));
			}
		}
	}
	
	/**
	 * Loading rules
	 */
	private function _loadRules() {
		
	}
	
	/**
	 * Utility method
	 */
	private function _prepareArray(array $array) {
		$count = count($array);
    	$temp = array();
    	for ($i = 0; $i < $count; $i++) {
    		$temp[] = $array[$i]['name'];
    	}
    	return $temp;
	}
	
	
}